package common;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;

/**
 * 
 * @author Flavio Ferrara
 * Classifica
 * Rappresenta la classifica dei giocatori: in gara, fuori gara, estinti
 * 
 * La chiave(int) è il totale dei punti realizzati. 
 * L'elemento(String[2]) contiene le informazioni relative all'utente (username, nome razza)
 * 
 * states 
 */
public class Ranking implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;


	private static Ranking ranking;
	
	
	private TreeMap<Integer, RankingEntry> rank;
	
	private Ranking(){
		this.rank = new TreeMap<Integer, RankingEntry>();
	}
	public static Ranking getRanking(){
		if (ranking == null){
			ranking = new Ranking();
		}
		
		return ranking;
	}
	
	public ArrayList<String> getPlayers(){
		ArrayList<String> players = new ArrayList<String>();
		for (RankingEntry e : this.rank.values()){
			players.add(e.getUsername()); 
		}
		
		return players;
	}
	
	public RankingEntry[] getRank(int toPosition){
		if (toPosition > this.rank.size())
			toPosition = this.rank.size();
		
		return this.rank.headMap(toPosition, true).values().toArray(new RankingEntry[toPosition]);
	}
	
	
	public void putPlayer(int score, String username, String speciesName){
		RankingEntry info = new RankingEntry(username, speciesName, score);
		
		if (this.rank.isEmpty()){
			this.rank.put(1, info);
		}
		for (Map.Entry<Integer, RankingEntry> e: this.rank.entrySet()){
			if (e.getValue().getSpeciesName().equals(speciesName))
				return;
		}
		for (Map.Entry<Integer, RankingEntry> e: this.rank.entrySet()){
			if (e.getValue().getScore() <= score){
				
				for (int i = this.rank.size() + 1;i > e.getKey();i--)
					this.rank.put(i, this.rank.get(i-1));
				this.rank.put(e.getKey(), info);
				
				break;
			}
		}
	}
	
	public void setPlaying(String username){
		for (RankingEntry e : this.rank.values()){
			if (e.getUsername().equals(username))
				e.setPlaying();
		}
	}
	
	// inutile
	public void setNotPlaying(String username){
		for (RankingEntry e : this.rank.values()){
			if (e.getUsername().equals(username))
				e.setNotPlaying();
		}
	}
	
	public void setExtinct(String username){
		for (RankingEntry e : this.rank.values()){
			if (e.getUsername().equals(username))
				e.setExtinct();
		}
	}
	
	public void updateScore(String username, int score){
		for (RankingEntry e : this.rank.values()){
			if (e.getUsername().equals(username)){
				e.updateScore(score);
			}
		}
	}
}
